﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;

// 加载一份资源
public class AssetsLoad
{
    // 当前已经加载的依赖资源
    static Dictionary<string, Object> AlreadyLoadList = new Dictionary<string, Object>();
    static public void Clear()
    {
        AlreadyLoadList.Clear();
    }

    public delegate void LoadEnd(GameObject obj, object p);

    static public AssetsLoad Load(string name, LoadEnd End, object p)
    {
        AssetsLoad assetsLoad = new AssetsLoad();
        assetsLoad.End = End;
        assetsLoad.Endp = p;
        assetsLoad.name = name;
        assetsLoad.DepList = AssetsDependencies.mInstance.GetAssetDepList(name); // 资源依赖
        if (assetsLoad.DepList.Length == 0)
        {
            // 没有依赖的资源，则直接加载
            ResourceDown.Instance.Load(ToUrl(assetsLoad.name), assetsLoad.ResLoadEnd, null);
        }
        else
        {
            // 需要先加载依赖资源
            assetsLoad.LoadDepAsset(0);
        }

        return assetsLoad;
    }

    public delegate void LoadResEnd(WWW www, object p);
    static public AssetsLoad LoadRes(string name, LoadResEnd End, object p)
    {
        AssetsLoad assetLoad = new AssetsLoad();
        assetLoad.End = End;
        assetLoad.Endp = p;
        assetLoad.name = name;

        ResourceDown.Instance.Load(ToUrl(assetLoad.name), assetLoad.OnLoadResEnd, null);
        return assetLoad;
    }

    void OnLoadResEnd(WWW www, object p)
    {
        if (www.assetBundle != null && www.assetBundle.mainAsset != null)
        {
            AlreadyLoadList[name] = www.assetBundle.mainAsset;
            if (End != null)
                ((LoadResEnd)End)(www, Endp);
        }
        else
        {
            AlreadyLoadList[name] = null;
            Logger.LogError("url:{0} == null!", www.url);
            if (End != null)
                ((LoadResEnd)End)(null, Endp);
        }
    }

    void LoadDepAsset(int index)
    {
        Logger.LogDebug(DepList[index]);
        if (AlreadyLoadList.ContainsKey(DepList[index])) // 资源已加载
        {
            if ((index+1) >= DepList.Length)
            {
                // 所有的依赖资源加载完成
                ResourceDown.Instance.Load(ToUrl(name), ResLoadEnd, null);
            }
            else
            {
                LoadDepAsset(index + 1);
            }
        }
        else
        {
            string url = ToUrl(DepList[index]);
            //ConsoleSelf.me.addText("load:{0}", url);
            // 需要加载依赖资源
            ResourceDown.Instance.Load(url, ResLoadEnd, index);
        }
    }

    static string ToUrl(string name)
    {
#if (UNITY_ANDROID || UNITY_IPHONE) && (!UNITY_EDITOR)
        return "file://" + ResourcesPath.LocalPath + name;
#else
        return "file://" + ResourcesPath.LocalPath + name;
#endif
    }

    void ResLoadEnd(WWW www, System.Object param)
    {
        Logger.LogDebug("{0} load End!", www.url);
        if (param == null)
        {
            // 已经加载完成了
            if (www.isDone == false)
            {
                Logger.LogDebug("{0} {1} res.www.isDone == false!", www.error, www.url);
            }
            else if (www.error != null)
            {
                Logger.LogDebug("{0} res.www.assetBundle == null!", www.error);
            }
            else if (www.assetBundle == null || www.assetBundle.mainAsset == null)
            {
                Logger.LogDebug("{0} res.www.assetBundle == null!", www.url);
            }
            else
            {
//                 GameObject newObj = (GameObject)www.assetBundle.mainAsset;
//                 AlreadyLoadList[name] = newObj;
                GameObject newObj = (GameObject)GameObject.Instantiate(www.assetBundle.mainAsset);
                if (End != null)
                    ((LoadEnd)End)(newObj, Endp);
            }
        }
        else
        {
            // 依赖资源加载完成
            int next = (int)(param) + 1;
            Object o;
            try
            {
                if (www.assetBundle != null && (o = www.assetBundle.mainAsset) != null)
                {
                    if (o.name == "Bark_02")
                        Debug.LogWarning(www.url);

                    AlreadyLoadList[DepList[next - 1]] = o;
                }
                else
                {
                    AlreadyLoadList[DepList[next - 1]] = null;
                    Logger.LogError("url:{0} == null!", www.url);
                }
            }
            catch (System.Exception ex)
            {
                AlreadyLoadList[DepList[next - 1]] = null;
                Logger.LogError("url:{0} error:{1}!", www.url, ex.Message);
            }

            if (next >= DepList.Length)
            {
                ResourceDown.Instance.Load(ToUrl(name), ResLoadEnd, null);
            }
            else
            {
                ResourceDown.Instance.Load(ToUrl(DepList[next]), ResLoadEnd, next);
            }
        }
    }

    string name; // 资源名
    string[] DepList; // 依赖的资源
    object End;
    object Endp;

    static string ToUrlAsset(string name)
    {
#if (UNITY_ANDROID || UNITY_IPHONE) && (!UNITY_EDITOR)
        return ResourcesPath.LocalPath + name;
#else
        return ResourcesPath.LocalPath + name;
#endif
    }

    // 同步方式加载资源
    static public GameObject LoadSync(string name)
    {
        string url;
        AssetBundle assetBundle;
        string[] DepList = AssetsDependencies.mInstance.GetAssetDepList(name); // 资源依赖
        // 需要先加载依赖资源
        foreach (string dep in DepList)
        {
            url = ToUrlAsset(dep);
            if (!AlreadyLoadList.ContainsKey(url))
            {
                // 当前还没有加载此份依赖资源
                assetBundle = ResourceDown.Instance.LoadSync(url);
                if (assetBundle != null && assetBundle.mainAsset != null)
                {
                    AlreadyLoadList[url] = assetBundle.mainAsset;
                }
                else
                {
                    AlreadyLoadList[url] = null;
                    Logger.LogError("LoadSync url:{0} == null!", url);
                }
            }
        }

        // 依赖加载完成之后
        url = ToUrlAsset(name);
        assetBundle = ResourceDown.Instance.LoadSync(url);
        if (!assetBundle)
        {
            Logger.LogError("loadsync:{0} url:{1} error!", name, url);
            return null;
        }

        Logger.LogDebug("loadsync:{0} url:{1} succ!", name, url);
        GameObject newObj = (GameObject)assetBundle.mainAsset;
        AlreadyLoadList[name] = newObj;
        newObj = (GameObject)GameObject.Instantiate(assetBundle.mainAsset);
        return newObj;
    }
}
